home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dirut / dosdir21.zip / DIRENT.C next >
C/C++ Source or Header  |  1994-06-22  |  7KB  |  258 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - dirent.c
  3.  *
  4.  * functions:
  5.  *        opendir       - opens a directory stream
  6.  *        readdir       - read entry from directory stream
  7.  *        rewinddir     - position directory stream at first entry
  8.  *        closedir      - close directory stream
  9.  *-----------------------------------------------------------------------*/
  10.  
  11. /*
  12.  *      C/C++ Run Time Library - Version 6.0
  13.  *
  14.  *      Copyright (c) 1991, 1993 by Borland International
  15.  *      All Rights Reserved.
  16.  *
  17.  * Modification History:
  18.  *  V1.0  15-Feb-94  Borland    Original version.
  19.  *  V1.1  22-Jun-94  J Mathews  Support VMS, non-Borland compilers,
  20.  *                and older Turbo C compilers;
  21.  *                Set d_namlen in readdir().
  22.  */
  23.  
  24. #include <errno.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include "dirent.h"
  28.  
  29. #define DIRMAGIC 0xdd
  30.  
  31. #if defined(MSDOS)
  32. #  ifdef __TURBOC__
  33. #    define FATTR        FA_HIDDEN|FA_SYSTEM|FA_RDONLY|FA_DIREC
  34. #    define FFIRST(n,d,a)    findfirst(n,(struct ffblk*)d,a)
  35. #    define FNEXT(d)        findnext((struct ffblk*)d)
  36. #    define FNAME        ff_name
  37. #  else /* !__TURBOC__ */
  38. #    define FATTR        _A_HIDDEN|_A_SYSTEM|_A_RDONLY|_A_SUBDIR
  39. #    define FFIRST(n,d,a)    _dos_findfirst(n,a,(struct find_t*)d)
  40. #    define FNEXT(d)        _dos_findnext((struct find_t*)d)
  41. #    define FNAME        name
  42. #  endif /* ?__TURBOC__ */
  43. #endif /* ?MSDOS */
  44.  
  45. #if defined(MSDOS)
  46.  
  47. DIR *  opendir(const char *dirname)
  48. {
  49.     char *name;
  50.     DIR *dir;
  51.     int len;
  52.  
  53.     /* Allocate space for a copy of the directory name, plus
  54.      * room for the "*.*" we will concatenate to the end.
  55.      */
  56.     len = strlen(dirname);
  57.     if ((name = malloc(len+5)) == NULL)
  58.         {
  59.             errno = ENOMEM;
  60.             return (NULL);
  61.         }
  62.     strcpy(name,dirname);
  63.     if (len-- && name[len] != ':' && name[len] != '\\' && name[len] != '/')
  64.             strcat(name,"\\*.*");
  65.     else
  66.             strcat(name,"*.*");
  67.  
  68.     /* Allocate space for a DIR structure.
  69.      */
  70.     if ((dir = malloc(sizeof(DIR))) == NULL)
  71.         {
  72.             errno = ENOMEM;
  73.             free(name);
  74.             return (NULL);
  75.         }
  76.  
  77.     /* Search for the first file to see if the directory exists,
  78.      * and to set up the DTA for future _dos_findnext() calls.
  79.      */
  80.     if (FFIRST(name, &dir->_d_reserved, FATTR) != 0)
  81.         {
  82.             free(name);
  83.             free(dir);
  84.             return (NULL);              /* findfirst sets errno for us */
  85.         }
  86.  
  87.     /* Everything is OK.  Save information in the DIR structure, return it.
  88.      */
  89.     dir->_d_dirname = name;
  90.     dir->_d_first = 1;
  91.     dir->_d_magic = DIRMAGIC;
  92.     return dir;
  93. }
  94.  
  95. void  rewinddir(DIR *dir)
  96. {
  97.     /* Verify the handle.
  98.      */
  99.     if (dir->_d_magic != DIRMAGIC)
  100.             return;
  101.  
  102.     /* Search for the first file and set up the DTA for future
  103.      * findnext() calls.
  104.      */
  105.     FFIRST(dir->_d_dirname, &dir->_d_reserved, FATTR);
  106.     dir->_d_first = 1;
  107. }
  108.  
  109. struct dirent *  readdir(DIR *dir)
  110. {
  111.     /* Verify the handle.
  112.      */
  113.     if (dir->_d_magic != DIRMAGIC)
  114.         {
  115.             errno = EBADF;
  116.             return (NULL);
  117.         }
  118.  
  119.     /* If this isn't the first file, call findnext() to get the next
  120.      * directory entry.  Opendir() fetches the first one.
  121.      */
  122.     if (!dir->_d_first)
  123.         {
  124.             if (FNEXT(&dir->_d_reserved) != 0)
  125.                 return (NULL);
  126.     }
  127.     dir->_d_dirent.d_namlen = strlen(dir->_d_dirent.d_name);
  128.     dir->_d_first = 0;
  129.     return &dir->_d_dirent;
  130. }
  131.  
  132. #elif defined(VMS)
  133.  
  134. DIR *  opendir(const char *dirname)
  135. {
  136.     char *name;
  137.     DIR *dir;
  138.     int len;
  139.     char *s;
  140.  
  141.     /* Allocate space for a copy of the directory name, plus
  142.      * room for the "*.*" we will concatenate to the end.
  143.      */
  144.     len = strlen(dirname);
  145.     if ((name = malloc(len+4)) == NULL)
  146.         {
  147.             errno = ENOMEM;
  148.             return (NULL);
  149.         }
  150.     strcpy(name,dirname);
  151.     strcpy(name+len, "*.*");
  152.  
  153.     /* Allocate space for a DIR structure.
  154.      */
  155.     if ((dir = malloc(sizeof(DIR))) == NULL)
  156.         {
  157.             errno = ENOMEM;
  158.             free(name);
  159.             return (NULL);
  160.         }
  161.  
  162.     dir->_d_fab = cc$rms_fab;
  163.     dir->_d_fab.fab$l_dna = name;
  164.     dir->_d_fab.fab$b_dns = len + 3;
  165.     dir->_d_fab.fab$l_nam = &dir->_d_nam;
  166.     dir->_d_nam = cc$rms_nam;
  167.     dir->_d_nam.nam$l_esa = dir->_d_esa;
  168.     dir->_d_nam.nam$b_ess = MAXNAMLEN;
  169.     dir->_d_nam.nam$l_rsa = dir->_d_rsa;
  170.     dir->_d_nam.nam$b_rss = MAXNAMLEN;
  171.  
  172.     /* Parse the directory to see if the directory exists,
  173.      * and to set up the FAB for readdir() calls.
  174.      */
  175.     if (SYS$PARSE(&dir->_d_fab, 0, 0) != RMS$_NORMAL)
  176.     {
  177.             free(name);
  178.             free(dir);
  179.         errno = ENOENT;        /* No file found */
  180.         return (NULL);
  181.     }
  182.  
  183.     /* Everything is OK.  Save information in the DIR structure, return it.
  184.      */
  185.     dir->_d_dirname = name;
  186.     dir->_d_magic = DIRMAGIC;
  187.     return dir;
  188. }
  189.  
  190. struct dirent *  readdir(DIR *dir)
  191. {
  192.     char* s;
  193.     /* Verify the handle.
  194.      */
  195.     if (dir->_d_magic != DIRMAGIC)
  196.         {
  197.             errno = EBADF;
  198.             return (NULL);
  199.         }
  200.  
  201.     /* Search the directory for the next directory entry.
  202.      */
  203.     if (SYS$SEARCH(&dir->_d_fab, 0, 0) != RMS$_NORMAL)
  204.     {
  205.         return NULL;
  206.     }
  207.  
  208.     /* Everything is OK.  Save filename information and return it.
  209.      */
  210.     dir->_d_rsa[dir->_d_nam.nam$b_rsl] = '\0';
  211.     s = strchr(dir->_d_rsa, DIR_END);
  212.     /* The directory name located in the filename is stripped with
  213.      * respect to readdir().
  214.      */
  215.     if (s != NULL) {
  216.     dir->_d_dirent.d_name   = ++s;  /* point to the filename */
  217.     dir->_d_dirent.d_namlen = dir->_d_nam.nam$b_rsl - (s - dir->_d_rsa);
  218.     }
  219.     else {
  220.     dir->_d_dirent.d_name   = dir->_d_rsa;
  221.     dir->_d_dirent.d_namlen = dir->_d_nam.nam$b_rsl;
  222.     }
  223.  
  224.     return &dir->_d_dirent;
  225. }
  226.  
  227. void  rewinddir(DIR *dir)
  228. {
  229.     /* Verify the handle.
  230.      */
  231.     if (dir->_d_magic == DIRMAGIC)
  232.     {
  233.         SYS$PARSE(&dir->_d_fab, 0, 0);
  234.     }
  235. }
  236.  
  237. #endif /* ?MSDOS */
  238.  
  239. #if defined(MSDOS) || defined(VMS)
  240.  
  241. int  closedir(DIR* dir)
  242. {
  243.     /* Verify the handle.
  244.      */
  245.     if (dir == NULL || dir->_d_magic != DIRMAGIC)
  246.         {
  247.             errno = EBADF;
  248.             return (-1);
  249.         }
  250.     dir->_d_magic = 0;          /* prevent use after closing */
  251.  
  252.     free(dir->_d_dirname);
  253.     free(dir);
  254.     return 0;
  255. }
  256.  
  257. #endif /* ?MSDOS|VMS */
  258.